using System;
using System.ComponentModel.Design.Serialization;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using Microsoft.WowAddonStudio.FrameXml.Design.Serialization;
using Microsoft.WowAddonStudio.FrameXml.Serialization.LayoutFrames;
using Microsoft.WowAddonStudio.Tests.Common.Mocks;

using NUnit.Framework;

namespace Microsoft.WowAddonStudio.FrameXml.Design.Tests.Serialization
{
	[TestFixture]
	public sealed class ComponentSerializationServiceTest : SerializationTestBase
	{
		private ComponentSerializationService componentSerializationService;

		#region SetUp

		[TestFixtureSetUp]
		public void TestFixtureSetUp()
		{
			locator = new SimpleTestServiceLocator();
			serializer = new FrameXmlRuntimeSerializer();
		}

		[SetUp]
		public void SetUp()
		{
			locator = new SimpleTestServiceLocator();
			serializer = new FrameXmlRuntimeSerializer();
			serializationStore = new FrameXmlSerializationStore(locator);
			componentSerializationService = new FrameXmlComponentSerializationService(locator, serializer);
		}

		#endregion

		#region TearDown

		[TearDown]
		public void TearDown()
		{
		}

		#endregion

		#region Tests

		[Test(Description = "")]
		public void Test_Serialize()
		{
			componentSerializationService.Serialize(serializationStore, CreateTestControl());
			Assert.IsNotNull(serializationStore);
			Assert.IsNotNull(serializationStore.Errors);
			Assert.AreEqual(1, serializationStore.Count);
		}

		[Test(Description = "")]
		public void Test_DeSerialize()
		{
			Test_Serialize();

			Assert.IsNotNull(serializationStore);
			Assert.IsNotNull(serializationStore.Errors);
			Assert.AreEqual(1, serializationStore.Count);

			var deserializedResult = componentSerializationService.Deserialize(serializationStore);

			Assert.IsNotNull(deserializedResult);
			Assert.AreEqual(1, deserializedResult.Count);
			var frame = deserializedResult.OfType<Frame>().SingleOrDefault();
			Assert.IsNotNull(frame);
			Assert.AreEqual("TestControl", frame.Name);
		}

		[Test(Description = "")]
		[ExpectedException(typeof (ArgumentNullException))]
		public void Test_Test_DeSerializeFailed()
		{
			componentSerializationService.Deserialize(null);
		}

		[Test(Description = "")]
		public void Test_CreateStore()
		{
			var store = componentSerializationService.CreateStore();
			Assert.IsNotNull(store);
			Assert.IsInstanceOfType(typeof (FrameXmlSerializationStore), store);
			Assert.AreEqual(0, ((FrameXmlSerializationStore) store).Count);
		}

		[Test(Description = "")]
		public void Test_LoadStore()
		{
			Test_Serialize();

			using (var stream = new MemoryStream())
			{
				new BinaryFormatter().Serialize(stream, serializationStore);
				stream.Position = 0;

				var store = componentSerializationService.LoadStore(stream);

				Assert.IsNotNull(store);
				Assert.IsInstanceOfType(typeof (FrameXmlSerializationStore), store);
				Assert.AreEqual(1, ((FrameXmlSerializationStore) store).Count);
			}
		}

		[Test(Description = "")]
		[ExpectedException(typeof(NotImplementedException))]
		public void Test_SerializeAbsolute()
		{
			componentSerializationService.SerializeAbsolute(serializationStore, null);
		}

		[Test(Description = "")]
		[ExpectedException(typeof(NotImplementedException))]
		public void Test_SerializeMember()
		{
			componentSerializationService.SerializeMember(serializationStore, null, null);
		}

		[Test(Description = "")]
		[ExpectedException(typeof(NotImplementedException))]
		public void SerializeMemberAbsolute()
		{
			componentSerializationService.SerializeMemberAbsolute(serializationStore, null, null);
		}

		[Test(Description = "")]
		[ExpectedException(typeof (ArgumentNullException))]
		public void Test_LoadStoreFailed()
		{
			componentSerializationService.LoadStore(null);
		}


		#endregion
	}
}